﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Threading;
using System.Windows.Navigation;
using Microsoft.Devices;
using com.google.zxing;
using com.google.zxing.common;
using com.google.zxing.qrcode;
using System.Collections.ObjectModel;
using System.Xml.Linq;
using System.IO;
using System.IO.IsolatedStorage;

namespace myDiet
{
    public partial class foodCheck : PhoneApplicationPage
    {
        int count;
        string fid;                                      //set "fid" is string variable
        FoodData Food;                                   //set new FoodData class, name "Food"
        UserData userItem;
        App app = App.Current as App;                    //set "app" for global variable [user profile]

        //set variable to use Camera of device and Scan QR code
        private readonly DispatcherTimer _timer;
        private readonly ObservableCollection<string> _matches;
        private PhotoCameraLuminanceSource _luminance;
        private QRCodeReader _reader;
        private PhotoCamera _photoCamera;

        public foodCheck()
        {
            InitializeComponent();
            _matches = new ObservableCollection<string>();

            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromMilliseconds(250);
            _timer.Tick += (o, arg) => ScanPreviewBuffer();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            _photoCamera = new PhotoCamera();
            _photoCamera.Initialized += OnPhotoCameraInitialized;
            _previewVideo.SetSource(_photoCamera);

            CameraButtons.ShutterKeyHalfPressed += (o, arg) => _photoCamera.Focus();

            base.OnNavigatedTo(e);
        }

        private void OnPhotoCameraInitialized(object sender, CameraOperationCompletedEventArgs e)
        {
            //set width and height of CameraViewer, binding with Resolution[width, height] of device
            int width = Convert.ToInt32(_photoCamera.PreviewResolution.Width);
            int height = Convert.ToInt32(_photoCamera.PreviewResolution.Height);

            _luminance = new PhotoCameraLuminanceSource(width, height);
            _reader = new QRCodeReader();

            Dispatcher.BeginInvoke(() =>
            {
                _previewTransform.Rotation = _photoCamera.Orientation;
                _timer.Start();
            });
        }

        private void ScanPreviewBuffer()
        {
            try
            {
                _photoCamera.GetPreviewBufferY(_luminance.PreviewBufferY);
                var binarizer = new HybridBinarizer(_luminance);
                var binBitmap = new BinaryBitmap(binarizer);
                var result = _reader.decode(binBitmap);
                Dispatcher.BeginInvoke(() => DisplayResult(result.Text));           //call DisplayResult method to show output
            }
            catch
            {
            }
        }

//=========================================== set format, show and save data from Scan QR code =========================================
        private void DisplayResult(string text)
        {
            //get food id from QR code, next compare with food id in database and show data if same 
            fid = text;

            //WebClient for get Food data
            WebClient foodClient = new WebClient();
            foodClient.DownloadStringAsync(new Uri("http://" + app.url + "/MyDiet/food_mobile.php", UriKind.RelativeOrAbsolute));   //load xml from web service [localhost]
            foodClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(foodClient_DownloadStringCompleted);
        }

        //event of foodClient when DownloadStringComplete.
        void foodClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                XElement foodElement = XElement.Parse(e.Result);

                var items = from item in foodElement.Descendants("FOODS")
                            where item.Element("ID").Value == fid
                            select Food = new FoodData
                            {
                                //feed value of elements to new FoodData class
                                Id = item.Element("ID").Value,
                                Name = item.Element("FOOD").Value,
                                Weight = item.Element("WEIGHT").Value,
                                Calorie = item.Element("CALORIE").Value,
                                Protien = item.Element("PROTEIN").Value,
                                Fat = item.Element("FAT").Value,
                                Carbohydrate = item.Element("CARBO").Value
                            };
                count = items.Count();      //count number of food by food id >> count == 1 [true]
                if (count == 0)
                {
                    MessageBox.Show("Input Type is Wrong, Please try again.");
                }
                else
                {
                    //WebClient for get cross1day.php >> calculate sum of calorie.
                    Random rand = new Random();
                    WebClient sumClient = new WebClient();
                    sumClient.DownloadStringAsync(new Uri("http://" + app.url + "/MyDiet/cross1day.php?r=" + rand.Next(), UriKind.RelativeOrAbsolute));
                    sumClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(sumClient_DownloadStringCompleted);
                }
            }
        }

        //event of sumClient when DownloadStringComplete.
        void sumClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            //set double variable for calculate sum of calorie and remaining.
            double temp, remaining = 0, sumCal = 0;

            if (e.Error == null)
            {
                XElement sumElement = XElement.Parse(e.Result);
                var items = from item in sumElement.Descendants("uid")
                            select new NutritionData
                            {
                                //feed value of "calorie" element
                                CAlorie = item.Element("calorie").Value
                            };

                foreach (var foodItem in items)
                {
                    //sum calorie of one day
                    sumCal += Convert.ToDouble(foodItem.CAlorie);
                }


                // open userXML.xml file and read data [Calorie Limit]
                string test;
                try
                {
                    // set variable refer to IsolatedStorageFile
                    using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        // set variable refer to IsolatedStorageFileStream
                        IsolatedStorageFileStream isoFileStream = myIsolatedStorage.OpenFile("userXML.xml", FileMode.Open);
                        using (StreamReader reader = new StreamReader(isoFileStream))
                        {
                            // read to end file
                            test = reader.ReadToEnd();

                            // set element for feed data from userXML.xml file
                            XElement element = XElement.Parse(test);
                            var items1 = from item1 in element.Descendants("user")
                                        select userItem = new UserData
                                        {
                                            Uid = item1.Element("uid").Value,
                                            Limit = item1.Element("limit_cal").Value
                                        };

                            // check items
                            int count1 = items1.Count();
                            if (count1 == 1)
                            {
                                temp = Convert.ToDouble(userItem.Limit);         //get limit of calorie from xml file >> in temp
                                remaining = temp - sumCal;                  //calculate for calorie can get !!
                            }
                            else MessageBox.Show("can not find userXML.xml file");
                        }
                    }
                }
                catch { MessageBox.Show("File not found !"); }


                // check remaining 
                if (remaining < 200 && Convert.ToInt16(Food.Calorie) > 200)
                {
                    MessageBox.Show(" !! >> Calorie Limit Exceeded << !! ");
                }
                else
                {
                    //set format for show in display
                    string result = "NAME : " + Food.Name + "\n" +
                                    "WEIGHT : " + Food.Weight + " g." + "\n" +
                                    "CALORIE : " + Food.Calorie + " kcal." + "\n" +
                                    "PROTEIN : " + Food.Protien + " g." + "\n" +
                                    "FAT : " + Food.Fat + " g." + "\n" +
                                    "CARBOHYDRATE : " + Food.Carbohydrate + " g." + "\n\n" +
                                    "Total Calorie >> " + sumCal.ToString() + " kcal." + "\n" +
                                    "Calorie can get >> " + remaining.ToString() + " kcal." + "\n";

                    if (MessageBox.Show(result, "Result", MessageBoxButton.OKCancel) != MessageBoxResult.Cancel)
                    {
                        //save data to database, send user id and food id 
                        WebClient sentClient = new WebClient();
                        sentClient.OpenReadAsync(new Uri("http://" + app.url + "/MyDiet/adddata.php?uid=" + userItem.Uid + "&fid=" + Food.Id));
                        sentClient.OpenReadCompleted += new OpenReadCompletedEventHandler(sentClient_OpenReadCompleted);
                    }
                    //else { }
                }
            }
        }

        //event of sentClient when OpenReadComplete.
        void sentClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            //save complete
            MessageBox.Show("save data complete !!");
        }
//===============================================================================================================================

        private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //close camera if click "BackKeyPress" button
            _photoCamera.Dispose();
        }

    }
}
